#include "includes.h"
#include "vehicle.h"
#include "stdcan.h"


void StdCan_init(void)
{

}

uint8_t StdCan_ioctl(StdCanData *data)
{
    uint8_t ret;
    uint8_t i, j;
    CanTxMsg txMsg;
    CanRxMsg rxMsg;
    //if has Module id, tx rx data[0] must be module_id
    uint8_t hasModuleId = FALSE;
    uint8_t hasSubCmd = FALSE;
    uint8_t index = 0;
    uint8_t rx_index = 0;
    uint8_t rxId;
    uint8_t first_rx_index = 0;
    uint8_t first_byte;
    uint8_t bytes;
    uint8_t packages;
    CanTxMsg continue_package =
    {
        0x00, 0x18db33f1,
        CAN_ID_STD, CAN_RTR_DATA,
        8,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    txMsg.StdId = data->tx_id;
    txMsg.IDE = CAN_ID_STD;
    continue_package.StdId = data->tx_id;
    txMsg.DLC = 8;
    if(data->module_id > 0) {
        hasModuleId = TRUE;
        first_rx_index = 1;
        continue_package.Data[0] = data->module_id;
        continue_package.Data[1] = 0x30;
    } else {
        hasModuleId = FALSE;
        first_rx_index = 0;
        continue_package.Data[0] = 0x30;
    }
    if(data->sub_cmd > 0)
        hasSubCmd = TRUE;
    else
        hasSubCmd = FALSE;

    if(hasModuleId) {
        txMsg.Data[index ++] = data->module_id;
    }
    txMsg.Data[index ++] = data->cmd_len;
    txMsg.Data[index ++] = data->cmd;
    if(hasSubCmd) {
        txMsg.Data[index ++] = data->sub_cmd;
    }
    txMsg.Data[index ++] = data->id;
    for(i = index; i < 8; i++) {
        txMsg.Data[i] = 0x00;
    }

    if(data->rx_id > 0)
        rxId = data->rx_id;
    else
        rxId = data->tx_id + 0x08;

    bsp_can_clear();
    bsp_can_filter(rxId, rxId, rxId | 0x00ff, rxId | 0x00ff);
    index = 0;
    if(vehicle_can_session(&txMsg, &rxMsg)) {
        first_byte = rxMsg.Data[first_rx_index];
        bytes = rxMsg.Data[first_rx_index + 1];
        packages = (bytes - 6 + first_rx_index) / (7 - first_rx_index);
        if((bytes - 6 + first_rx_index) % (7 - first_rx_index) > 0) {
            packages ++;
        }
        //short package
        rx_index = index_of_buf(rxMsg.Data, 8, data->cmd + 0x40) + 1;
        for(i = rx_index; i < 8; i++) {
            data->rx_data[index ++] = rxMsg.Data[i];
        }
        if(first_byte == 0x10) {
            //multipackage
            //need to send continue package
            if(vehicle_can_session(&continue_package, &rxMsg)) {
                for(i = first_rx_index + 1; i < 8; i++) {
                    data->rx_data[index ++] = rxMsg.Data[i];
                }
                packages --;
                for(i = 0; i < packages; i++) {
                    if(vehicle_can_recv(&rxMsg)) {
                        for(j = first_rx_index + 1; j < 8; j++) {
                            data->rx_data[index ++] = rxMsg.Data[j];
                        }
                    }
                }
            }
        }
        data->rx_bytes = index;
    } else {
        ret = FALSE;
        goto STD_END;
    }
    ret = TRUE;

STD_END:
    return ret;
}
